#include "lightGenerator.h"
#include "lightPool.h"
#include "lightContainers.h"
#include <time.h>
#include "randoma.h"

#define NUM_SPOT_LIGHT_COLORS 8

const vec3 colors[] = {vec3(1.0f, 1.0f, 1.0f), vec3(0.0f, 0.0f, 1.0f), vec3(0.0f, 1.0f, 0.0f), vec3(1.0f, 0.0f, 0.0f),
	vec3(1.0f, 1.0f, 0.0f), vec3(0.0f, 1.0f, 1.0f), vec3(1.0f, 0.0f, 1.0f), vec3(1.0f, 1.0f, 1.0f) };

void generateRandomPointLights(unsigned int numLights, vec3 firstCorner, vec3 secondCorner, float scaleFactor) {
	CRandomMersenneA random(/*int(time(NULL))*/ 183);

	ds_LightPool* lp = ds_LightPool::Instance();

	vec3 mins, maxes, range;
	mins.x = firstCorner.x > secondCorner.x ? secondCorner.x : firstCorner.x;
	mins.y = firstCorner.y > secondCorner.y ? secondCorner.y : firstCorner.y;
	mins.z = firstCorner.z > secondCorner.z ? secondCorner.z : firstCorner.z;
	maxes.x = firstCorner.x > secondCorner.x ? firstCorner.x : secondCorner.x;
	maxes.y = firstCorner.y > secondCorner.y ? firstCorner.y : secondCorner.y;
	maxes.z = firstCorner.z > secondCorner.z ? firstCorner.z : secondCorner.z;

	range = maxes - mins;

	vec3 pos;
	for(unsigned int i = 0; i < numLights; ++i) {
		pos = mins + vec3(range.x*float(random.Random()), range.y*float(random.Random()), range.z*float(random.Random()));

		lp->addPointLight(pos, scaleFactor*colors[(unsigned int)random.IRandomX(0, NUM_SPOT_LIGHT_COLORS - 1)], 0.0f, 5.0f);
	}
}

void generateRandomSpotLights(unsigned int numLights, vec3 firstCorner, vec3 secondCorner, float scaleFactor, vec3 down, bool canPointUp) {
	CRandomMersenneA random(int(time(NULL)));

	ds_LightPool* lp = ds_LightPool::Instance();

	vec3 mins, maxes, range;
	mins.x = firstCorner.x > secondCorner.x ? secondCorner.x : firstCorner.x;
	mins.y = firstCorner.y > secondCorner.y ? secondCorner.y : firstCorner.y;
	mins.z = firstCorner.z > secondCorner.z ? secondCorner.z : firstCorner.z;
	maxes.x = firstCorner.x > secondCorner.x ? firstCorner.x : secondCorner.x;
	maxes.y = firstCorner.y > secondCorner.y ? firstCorner.y : secondCorner.y;
	maxes.z = firstCorner.z > secondCorner.z ? firstCorner.z : secondCorner.z;

	range = maxes - mins;

	vec3 pos, dir;
	float half_angle;
	for(unsigned int i = 0; i < numLights; ++i) {
		pos = mins + vec3(range.x*float(random.Random()), range.y*float(random.Random()), range.z*float(random.Random()));
		half_angle = (float(5.0f + 10.0f*random.Random()));

		dir = normalize(vec3(1.0f - 2.0f*random.Random(), 1.0f - 2.0f*random.Random(), 1.0f - 2.0f*random.Random()));
		if(!canPointUp)
			while(dot(dir, down) < .2f) {
				float f = dot(dir,down);
				dir = normalize(vec3(1.0f - 2.0f*random.Random(), 1.0f - 2.0f*random.Random(), 1.0f - 2.0f*random.Random()));
			}

		lp->addSpotLight(pos, dir, scaleFactor*colors[(unsigned int)random.IRandomX(0, NUM_SPOT_LIGHT_COLORS - 1)], half_angle, 12.0f, 25.0f);
	}
}

void setupPointLights() {
	ds_LightPool::Instance()->addPointLight(vec3(5.0f, 0.0f, 5.0f),vec3(1.0f, .0f, .0f));
	//ds_LightPool::Instance()->addPointLight(vec3(0.0f, 20.0f, 5.0f),vec3(.8f, 1.0f, .8f));
	//ds_LightPool::Instance()->addPointLight(vec3(-20.0f, -10.0f, 10.0f),vec3(.8f, .8f, 1.0f));

	// Near floor for help debugging
	//ds_LightPool::Instance()->addPointLight(vec3(10.0f, 0.0f, 2.0f),vec3(.8f, 1.0f, .8f));
}

void setupDirectionalLights() {
	ds_LightPool::Instance()->addDirectionalLight(normalize(vec3(-1.0f, 0.0f, 1.0f)),vec3(.2f, .2f, .2f));
	ds_LightPool::Instance()->addDirectionalLight(normalize(vec3(0.0f, -1.0f, 0.0f)),vec3(.1f, .4f, .1f));
}